# 代码功能说明：
# 实现了一个简单的神经网络类simpleNet
# 包含权重初始化、预测和损失计算功能
# 使用softmax激活函数和交叉熵误差函数
# 演示了如何计算神经网络权重的梯度
# 通过数值梯度法(numerical_gradient)计算梯度
# 关键点：
# 权重矩阵W是2x3的随机矩阵
# 输入x是2维向量，输出是3维向量
# 使用lambda函数封装损失计算，便于梯度计算
# 梯度dW表示损失函数对权重W的偏导数
# 输出结果显示了每个权重对损失函数的影响程度

# 指定文件编码为UTF-8
# coding: utf-8

# 导入系统模块和操作系统模块
import sys, os
# 添加父目录到系统路径，以便导入父目录中的模块
sys.path.append(os.pardir)  # 为了导入父目录中的文件而进行的设定

# 导入NumPy数值计算库
import numpy as np
# 从common.functions模块导入softmax和交叉熵误差函数
from common.functions import softmax, cross_entropy_error
# 从common.gradient模块导入数值梯度计算函数
from common.gradient import numerical_gradient

# 定义一个简单的神经网络类
class simpleNet:
    # 初始化函数
    def __init__(self):
        # 随机初始化2x3的权重矩阵
        self.W = np.random.randn(2,3)

    # 预测函数
    def predict(self, x):
        # 计算输入x和权重W的点积
        return np.dot(x, self.W)

    # 损失函数
    def loss(self, x, t):
        # 计算预测值
        z = self.predict(x)
        # 对预测值应用softmax激活函数
        y = softmax(z)
        # 计算交叉熵误差
        loss = cross_entropy_error(y, t)
        return loss

# 定义输入数据
x = np.array([0.6, 0.9])
# 定义目标标签(one-hot编码)
t = np.array([0, 0, 1])

# 创建simpleNet实例
net = simpleNet()

# 定义lambda函数用于计算损失
f = lambda w: net.loss(x, t)
# 计算权重矩阵的数值梯度
dW = numerical_gradient(f, net.W)

# 打印梯度值
print(dW)
